/*
 * Copyright (c)e 2024-2024.Powered by 清明雨揽月
 * This software is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
 * NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include "sequence_string.h"
#include "iostream"

using namespace std;

void SEQUENCE_STRING::operate()
{
    for (int index = 0; index < sizeof(_arr); index++)
    {
        _s_string->ch[index] = _arr[index];
        _t_string->ch[index] = _arr[index];
        if (_arr[index] != '\0')
        {
            _s_string->length = index + 1;
            _t_string->length = index + 1;
        }
        else
        {
            break;
        }
    }
    const int length = str_length();
    cout << "当前串的长度为：" << length << endl;
    cout << "串比较：" << str_compare(_t_string) << endl;
    str_copy();
    auto* t = new S_STRING();
    for (int index = 0; index < sizeof(_arr_test); index++)
    {
        t->ch[index] = _arr_test[index];
        if (_arr_test[index] != '\0')
        {
            t->length = index + 1;
        }
        else
        {
            break;
        }
    }
    const int i = index(t);
    free(t);
    cout << "简单匹配：" << i << endl;
    clear_string();
    destroy_string();
}

/**
 * index(S_STRING t)
 * 简单匹配模式算法（暴力匹配算法）
 * @param t
 * @return
 */
int SEQUENCE_STRING::index(const S_STRING* t) const
{
    int i = 0, j = 0;
    while (i <= _s_string->length && j <= t->length)
    {
        if (t->ch[j] != '\0')
        {
            cout << _s_string->ch[i] << ":" << t->ch[j] << (_s_string->ch[i] == t->ch[j]
                                                                ? " >>> 字符匹配："
                                                                : " >>> 字符不匹配：") << i << endl;
        }
        else
        {
            cout << "子串匹配结束" << endl;
        }
        if (_s_string->ch[i] == t->ch[j])
        {
            ++i;
            ++j;
        }
        else
        {
            if (t->ch[j] != '\0')
            {
                i = i - j + 1;
                j = 0;
            }
            else
            {
                ++j;
                ++i;
                break;
            }
        }
    }
    if (j > t->length)
    {
        return i - t->length;
    }
    return 0;
}

void SEQUENCE_STRING::str_assign()
{
}

void SEQUENCE_STRING::str_copy() const
{
    S_STRING s{};
    cout << ">>> 串开始复制 >>>" << endl;
    s.length = _s_string->length;
    for (int index = 0; index < sizeof(_s_string->ch); ++index)
    {
        s.ch[index] = _s_string->ch[index];
    }
    cout << ">>> 串复制完成 >>>" << endl;
    cout << "复制后的串的长度为：" << s.length << endl;
    cout << "复制后的串的内容为：" << s.ch << endl;
}

bool SEQUENCE_STRING::str_empty() const
{
    if (_s_string->length == 0)
    {
        cout << "当前串为空" << endl;
        return true;
    }
    cout << "当前串不为空" << endl;
    return false;
}

int SEQUENCE_STRING::str_length() const
{
    const int length = _s_string->length;
    return length;
}

void SEQUENCE_STRING::destroy_string() const
{
    free(_s_string);
    free(_t_string);
}

void SEQUENCE_STRING::clear_string() const
{
    cout << ">>> 开始清空串 >>>" << endl;
    _s_string->length = 0;
    memset(_s_string->ch, '\0', sizeof(_s_string->ch));
    cout << ">>> 清空串完成 >>>" << endl;
}

void SEQUENCE_STRING::concat()
{
}

void SEQUENCE_STRING::sub_string()
{
}

int SEQUENCE_STRING::str_compare(const S_STRING* data) const
{
    if (_s_string->length > data->length)
        return 1;
    else if (_s_string->length == data->length)
        return 0;
    else
        return -1;
}

/**
 * get_next(const S_STRING* t, int next[])
 * 获取next数组
 * @param t
 * @param next
 */
void SEQUENCE_STRING::get_next(const S_STRING* t, int next[]) const
{
    int i = 1, j = 0;
    next[1] = 0;
    while (i <= _s_string->length)
    {
        if (j == 0 || t->ch[i] == t->ch[j])
        {
            ++i;
            ++j;
            next[i] = j;
        }
        else
        {
            j = next[j];
        }
    }
}

/**
 * index_kmp(const S_STRING* t, const int next[])
 * kmp算法
 * @param t
 * @param next
 * @return
 */
int SEQUENCE_STRING::index_kmp(const S_STRING* t, const int next[]) const
{
    int i = 1, j = 1;
    while (i <= _s_string->length && j <= t->length)
    {
        if (j == 0 || _s_string->ch[i] == t->ch[j])
        {
            ++i;
            ++j;
        }
        else
        {
            j = next[j];
        }
    }
    if (j > t->length)
    {
        return i - t->length;
    }
    return 0;
}
